React enables developers to write reusable code in the form of components. This modular approach makes it simple to develop robust apps by following a parent-child structure and adding those components in as many times as needed. To configure a component, you can use props (data you pass to the component) whereas state allows you to manage the data that may change inside of that specific component. In other words, with state you can control how it behaves and renders. This guide will demonstrate how to make a parent component aware of actions or changes in the child by passing state as props. Although we will use functional components, the same applies to class-based ones.
To illustrate, we will store an array of
basketball players as objects in the state of
the main app component. Next, we will pass
that piece of state to a child (Player) component for visualization purposes.
Finally, we will set up a function to remove
players one by one and see how that impacts
the state of the parent. The final
code—including all the files—is available in
Codesandbox
and
GitHub.
To begin, create the following App.js file:
1import React, { useState } from "react";
2import Player from "./components/Player/Player";
3import "./styles.css";
4
5export default function App() {
6 const [players, setPlayers] = useState([
7 {
8 name: "LaMarcus Aldridge",
9 yearsPro: 14,
10 position: "Center-Forward"
11 },
12 {
13 name: "Marco Belinelli",
14 yearsPro: 13,
15 position: "Guard"
16 },
17 {
18 name: "DeMar DeRozan",
19 yearsPro: 11,
20 position: "Guard-Forward"
21 }
22 ]);
23
24 const playersList = players.map(({ name, yearsPro, position }) => (
25 <li key={name.replace(" ", "").toLowerCase()}>
26 <Player
27 allPlayers={players}
28 removePlayer={setPlayers}
29 name={name}
30 yearsPro={yearsPro}
31 position={position}
32 />
33 </li>
34 ));
35
36 return (
37 <div className="App">
38 <h1>Team Members ({players.length})</h1>
39 <ul className="List">{playersList}</ul>
40 </div>
41 );
42}
Now, examine what you have so far step by step.
1import React, { useState } from "react";
2import Player from "./components/Player/Player";
3import "./styles.css";
React (as expected) and the
useState
hook. The latter will allow you to
access and manipulate the state of the
current component.
A
Player
component (which you will add later)
The CSS file used for styling
2) A list of basketball players. Through
useState, you initialize a piece of state in a
variable named
players
and a function (setPlayers) to update it later
1const [players, setPlayers] = useState([
2 {
3 name: "LaMarcus Aldridge",
4 yearsPro: 14,
5 position: "Center-Forward"
6 },
7 {
8 name: "Marco Belinelli",
9 yearsPro: 13,
10 position: "Guard"
11 },
12 {
13 name: "DeMar DeRozan",
14 yearsPro: 11,
15 position: "Guard-Forward"
16 }
17]);
3) An array that consists of a series of
children components. Here you will be passing
the state (the
players
variable and the
setPlayers
function) as props to each instance of
Player. This will allow you to manipulate the
parent's state from each child.
1 const playersList = players.map(({ name, yearsPro, position }) => (
2 <li key={name.replace(" ", "").toLowerCase()}>
3 <Player
4 allPlayers={players}
5 removePlayer={setPlayers}
6 name={name}
7 yearsPro={yearsPro}
8 position={position}
9 />
10 </li>
11 ));
4) The
return
statement that will display the number and
list of players (which you will modify via the
state):
1return (
2 <div className="App">
3 <h1>Team Members ({players.length})</h1>
4 <ul className="List">{playersList}</ul>
5 </div>
6);
Once you put the child component in place in
the next section, you will observe how the
number of players (players.length) and therefore the list itself (playersList) are impacted by actions that occur in it.
The
Player
component consists of a
span
element that displays the player's name,
position, and years of experience. In
addition, the
handleRemove
function will make it possible to remove each
player from the parent's state when you click
on the corresponding item in the list. To
accomplish this, insert the following lines in
a file called
Player.js:
1import React from "react";
2import "./Player.css";
3
4// Destructuring props in the function arguments.
5const Player = ({ allPlayers, name, yearsPro, position, removePlayer }) => {
6 const handleRemove = () => {
7 const filteredPlayers = allPlayers.filter((player) => player.name !== name);
8 removePlayer(filteredPlayers);
9 };
10
11 return (
12 <span onClick={handleRemove}>
13 {name} ({position}) | Years pro: {yearsPro}
14 </span>
15 );
16};
17
18export default Player;
At this point, you should see the following in the browser:

Next up, see what happens when the
handleRemove
function is triggered in a given
Player
component.
Now that you have set up the state in the parent and passed it to the child as props, click on any of the players and see how it is removed from the list:

As you can see, the number of players is now two. If you click on another player, it will decrease to one:

Thus, you can confirm that the actual list of
players (which resides in
App.js) is modified when you manipulate the props
in
Player.
Alternatively, you can inspect the components using the React Developer Tools:

First, click on App and observe its state under the Hooks section on the right pane. Second, click on a given player component and examine its props. Finally, click on any of the items in the page and see how the state and props of the parent and child components are updated, respectively.
While the example in this guide is rather simple, you will find this same principle in all kinds of React-based apps. For example, you can think of a shopping cart with the total price as the parent component and each purchased item with its corresponding subtotal and individual quantity as a child.
Passing state as props from parent to child components is a core concept of React. By keeping state in only a few components and passing it to as many children as needed in the form of props, you will be able to write code that is easier to maintain, and you will thank yourself down the road.